const PROFILE_TOKEN_ERROR = 'ProfileToken cannot null!';
const FN_SUCCESS = fnName => `The ${fnName} function is success!`;
function base(device) {
    const MEDIA = device.services.media;
    const PTZ = device.services.ptz;

    const getInformation = () => device.getInformation();
    const getCurrentProfile = () => device.getCurrentProfile();
    
    const getStreamUri = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        if (!params.Protocol) params.Protocol = 'RTSP';
        try {
            const { data } = await MEDIA.getStreamUri(params);
            return { type: 'success', message: FN_SUCCESS('getStreamUri'), data: data.GetStreamUriResponse.MediaUri }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const getStatus = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        try {
            const { data } = await PTZ.getStatus(params);
            return { type: 'success', message: FN_SUCCESS('getStatus'), data }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const getCurrentPostiton = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        const res = await getStatus(params);
        if (res.type === 'error') return res;
        const { data } = res;
        const { PanTilt, Zoom } = data.GetStatusResponse.PTZStatus.Position;
        const pos = {
            x: PanTilt['$'].x,
            y: PanTilt['$'].y,
            z: Zoom['$'].x
        }
        return pos;
    };
    const getConfOpts = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        try {
            const { data } = await PTZ.getConfigurationOptions(params);
            return { type: 'success', message: FN_SUCCESS('getConfOpts'), data }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const getPresets = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        try {
            const { data } = await PTZ.getPresets(params);
            return { type: 'success', message: FN_SUCCESS('getPresets'), data }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const setPreset = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        try {
            const { data } = await PTZ.setPreset(params);
            return { type: 'success', message: FN_SUCCESS('setPreset'), data }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const getSnapshotUri = async (params) => {
        if (!params.ProfileToken) return { type: 'error', message: PROFILE_TOKEN_ERROR };
        try {
            const { data } = await MEDIA.getSnapshotUri(params);
            return { type: 'success', message: FN_SUCCESS('getSnapshotUri'), data: data.GetSnapshotUriResponse.MediaUri }
        } catch (error) {
            return { type: 'error', message: error.message }
        }
    };
    const fetchSnapshot = async () => {
        device.fetchSnapshot().then((res) => {
            // Determine the file extention
            let ext = 'bin';
            let mime_pair = res.headers['content-type'].split('/');
            if(mime_pair[0] === 'image') {
              ext = mime_pair[1];
            }
            // Save the data to a file
            let fname = 'snapshot.' + ext;
            fs.writeFileSync(fname, res.body, {encoding: 'binary'});
            console.log('Done!');
          }).catch((error) => {
            console.error(error);
          });
    }
    return {
        getInformation,
        getStreamUri,
        getCurrentProfile,
        getCurrentPostiton,
        getStatus,
        getConfOpts,
        getPresets,
        setPreset,
        getSnapshotUri,
        fetchSnapshot
    }
}
module.exports = base;